import 'package:flutter/material.dart';

/// UI组件库动画配置
/// 统一管理所有动画参数和曲线
class UIAnimationConfig {
  // 动画时长
  static const Duration ultraFast = Duration(milliseconds: 75);
  static const Duration fast = Duration(milliseconds: 150);
  static const Duration normal = Duration(milliseconds: 250);
  static const Duration slow = Duration(milliseconds: 350);
  static const Duration slower = Duration(milliseconds: 500);
  static const Duration slowest = Duration(milliseconds: 750);

  // 特殊动画时长
  static const Duration microInteraction = ultraFast;
  static const Duration quickTransition = fast;
  static const Duration standardTransition = normal;
  static const Duration complexTransition = slow;
  static const Duration pageTransition = slower;
  static const Duration modalTransition = slowest;

  // 动画曲线
  static const Curve easeIn = Curves.easeIn;
  static const Curve easeOut = Curves.easeOut;
  static const Curve easeInOut = Curves.easeInOut;
  static const Curve linear = Curves.linear;
  static const Curve bounceIn = Curves.bounceIn;
  static const Curve bounceOut = Curves.bounceOut;
  static const Curve elastic = Curves.elasticOut;
  static const Curve decelerate = Curves.decelerate;
  static const Curve fastOutSlowIn = Curves.fastOutSlowIn;

  // Material Design 3 动画曲线
  static const Curve emphasized = Cubic(0.2, 0.0, 0, 1.0);
  static const Curve emphasizedDecelerate = Cubic(0.05, 0.7, 0.1, 1.0);
  static const Curve emphasizedAccelerate = Cubic(0.3, 0.0, 0.8, 0.15);
  static const Curve standard = Cubic(0.2, 0.0, 0, 1.0);
  static const Curve standardDecelerate = Cubic(0.0, 0.0, 0, 1.0);
  static const Curve standardAccelerate = Cubic(0.3, 0.0, 1.0, 1.0);

  // 组件特定动画配置
  static AnimationConfig get button => AnimationConfig(
    duration: microInteraction,
    curve: fastOutSlowIn,
  );

  static AnimationConfig get card => AnimationConfig(
    duration: quickTransition,
    curve: emphasized,
  );

  static AnimationConfig get dialog => AnimationConfig(
    duration: complexTransition,
    curve: emphasizedDecelerate,
  );

  static AnimationConfig get bottomSheet => AnimationConfig(
    duration: complexTransition,
    curve: emphasizedDecelerate,
  );

  static AnimationConfig get listItem => AnimationConfig(
    duration: quickTransition,
    curve: standard,
  );

  static AnimationConfig get pageRoute => AnimationConfig(
    duration: pageTransition,
    curve: emphasized,
  );

  static AnimationConfig get snackbar => AnimationConfig(
    duration: standardTransition,
    curve: standardDecelerate,
  );

  static AnimationConfig get tooltip => AnimationConfig(
    duration: quickTransition,
    curve: standard,
  );

  static AnimationConfig get fab => AnimationConfig(
    duration: standardTransition,
    curve: emphasizedDecelerate,
  );

  // 状态动画配置
  static AnimationConfig get loading => AnimationConfig(
    duration: normal,
    curve: linear,
    repeat: true,
  );

  static AnimationConfig get skeleton => AnimationConfig(
    duration: Duration(milliseconds: 1500),
    curve: easeInOut,
    repeat: true,
  );

  static AnimationConfig get pulse => AnimationConfig(
    duration: Duration(milliseconds: 1000),
    curve: easeInOut,
    repeat: true,
  );

  static AnimationConfig get bounce => AnimationConfig(
    duration: Duration(milliseconds: 800),
    curve: bounceOut,
  );

  static AnimationConfig get shake => AnimationConfig(
    duration: Duration(milliseconds: 600),
    curve: elastic,
  );

  // 入场动画配置
  static AnimationConfig get slideInUp => AnimationConfig(
    duration: standardTransition,
    curve: emphasizedDecelerate,
  );

  static AnimationConfig get slideInDown => AnimationConfig(
    duration: standardTransition,
    curve: emphasizedDecelerate,
  );

  static AnimationConfig get slideInLeft => AnimationConfig(
    duration: standardTransition,
    curve: emphasizedDecelerate,
  );

  static AnimationConfig get slideInRight => AnimationConfig(
    duration: standardTransition,
    curve: emphasizedDecelerate,
  );

  static AnimationConfig get fadeIn => AnimationConfig(
    duration: quickTransition,
    curve: easeOut,
  );

  static AnimationConfig get scaleIn => AnimationConfig(
    duration: standardTransition,
    curve: emphasizedDecelerate,
  );

  static AnimationConfig get zoomIn => AnimationConfig(
    duration: standardTransition,
    curve: emphasized,
  );

  // 出场动画配置
  static AnimationConfig get slideOutUp => AnimationConfig(
    duration: quickTransition,
    curve: emphasizedAccelerate,
  );

  static AnimationConfig get slideOutDown => AnimationConfig(
    duration: quickTransition,
    curve: emphasizedAccelerate,
  );

  static AnimationConfig get slideOutLeft => AnimationConfig(
    duration: quickTransition,
    curve: emphasizedAccelerate,
  );

  static AnimationConfig get slideOutRight => AnimationConfig(
    duration: quickTransition,
    curve: emphasizedAccelerate,
  );

  static AnimationConfig get fadeOut => AnimationConfig(
    duration: fast,
    curve: easeIn,
  );

  static AnimationConfig get scaleOut => AnimationConfig(
    duration: quickTransition,
    curve: emphasizedAccelerate,
  );

  // 创建自定义动画配置
  static AnimationConfig custom({
    required Duration duration,
    required Curve curve,
    bool repeat = false,
    bool reverse = false,
  }) {
    return AnimationConfig(
      duration: duration,
      curve: curve,
      repeat: repeat,
      reverse: reverse,
    );
  }

  // 获取预设动画配置
  static AnimationConfig getConfig(String name) {
    switch (name.toLowerCase()) {
      case 'button':
        return button;
      case 'card':
        return card;
      case 'dialog':
        return dialog;
      case 'bottomsheet':
        return bottomSheet;
      case 'listitem':
        return listItem;
      case 'pageroute':
        return pageRoute;
      case 'snackbar':
        return snackbar;
      case 'tooltip':
        return tooltip;
      case 'fab':
        return fab;
      case 'loading':
        return loading;
      case 'skeleton':
        return skeleton;
      case 'pulse':
        return pulse;
      case 'bounce':
        return bounce;
      case 'shake':
        return shake;
      case 'slideinup':
        return slideInUp;
      case 'slideindown':
        return slideInDown;
      case 'slideinleft':
        return slideInLeft;
      case 'slideinright':
        return slideInRight;
      case 'fadein':
        return fadeIn;
      case 'scalein':
        return scaleIn;
      case 'zoomin':
        return zoomIn;
      case 'slideoutup':
        return slideOutUp;
      case 'slideoutdown':
        return slideOutDown;
      case 'slideoutleft':
        return slideOutLeft;
      case 'slideoutright':
        return slideOutRight;
      case 'fadeout':
        return fadeOut;
      case 'scaleout':
        return scaleOut;
      default:
        return AnimationConfig(
          duration: standardTransition,
          curve: standard,
        );
    }
  }

  // 创建补间动画
  static Tween<double> createTween({
    double begin = 0.0,
    double end = 1.0,
  }) {
    return Tween<double>(begin: begin, end: end);
  }

  // 创建偏移补间
  static Tween<Offset> createOffsetTween({
    required Offset begin,
    required Offset end,
  }) {
    return Tween<Offset>(begin: begin, end: end);
  }

  // 创建颜色补间
  static ColorTween createColorTween({
    required Color? begin,
    required Color? end,
  }) {
    return ColorTween(begin: begin, end: end);
  }

  // 创建大小补间
  static Tween<Size> createSizeTween({
    required Size begin,
    required Size end,
  }) {
    return Tween<Size>(begin: begin, end: end);
  }

  // 创建矩形补间
  static RectTween createRectTween({
    required Rect? begin,
    required Rect? end,
  }) {
    return RectTween(begin: begin, end: end);
  }

  // 动画延迟配置
  static const Duration noDelay = Duration.zero;
  static const Duration shortDelay = Duration(milliseconds: 50);
  static const Duration mediumDelay = Duration(milliseconds: 100);
  static const Duration longDelay = Duration(milliseconds: 200);

  // 交错动画延迟
  static Duration staggerDelay(int index, {Duration baseDelay = shortDelay}) {
    return Duration(milliseconds: baseDelay.inMilliseconds * index);
  }

  // 动画状态检查工具
  static bool isAnimationCompleted(AnimationController controller) {
    return controller.status == AnimationStatus.completed;
  }

  static bool isAnimationRunning(AnimationController controller) {
    return controller.status == AnimationStatus.forward ||
           controller.status == AnimationStatus.reverse;
  }

  static bool isAnimationDismissed(AnimationController controller) {
    return controller.status == AnimationStatus.dismissed;
  }

  // 动画监听器辅助方法
  static void addStatusListener(
    AnimationController controller,
    void Function(AnimationStatus status) listener,
  ) {
    controller.addStatusListener(listener);
  }

  static void addListener(
    AnimationController controller,
    VoidCallback listener,
  ) {
    controller.addListener(listener);
  }

  // 动画性能优化
  static Widget optimizedAnimatedBuilder({
    required Animation<double> animation,
    required Widget Function(BuildContext, Widget?) builder,
    Widget? child,
  }) {
    return AnimatedBuilder(
      animation: animation,
      builder: builder,
      child: child,
    );
  }
}

/// 动画配置数据类
class AnimationConfig {
  final Duration duration;
  final Curve curve;
  final bool repeat;
  final bool reverse;

  const AnimationConfig({
    required this.duration,
    required this.curve,
    this.repeat = false,
    this.reverse = false,
  });

  AnimationConfig copyWith({
    Duration? duration,
    Curve? curve,
    bool? repeat,
    bool? reverse,
  }) {
    return AnimationConfig(
      duration: duration ?? this.duration,
      curve: curve ?? this.curve,
      repeat: repeat ?? this.repeat,
      reverse: reverse ?? this.reverse,
    );
  }

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) return true;
    return other is AnimationConfig &&
        other.duration == duration &&
        other.curve == curve &&
        other.repeat == repeat &&
        other.reverse == reverse;
  }

  @override
  int get hashCode {
    return Object.hash(duration, curve, repeat, reverse);
  }
}